﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UseCaseBindService.cs" company="">
//   
// </copyright>
// <summary>
//   The use case bind service.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.Bindings
{
    using Libium.UseCases;
    using Libium.Views;

    /// <summary>
    ///   The use case bind service.
    /// </summary>
    public class UseCaseBindService : BindService
    {
        #region Constructors and Destructors

        /// <summary>
        ///   Initializes a new instance of the <see cref="UseCaseBindService" /> class.
        /// </summary>
        public UseCaseBindService()
        {
            AddBinder<ICommand, ICommandView>((service, element, view) => new CommandBinding(service, element, view));
            AddBinder<ICommandMenu, ICommandMenuView>(
                (service, element, view) => new CommandMenuBinding(service, element, view));
            AddBinder<ITextUseCase, ITextView>((service, element, view) => new TextBinding(service, element, view));
            AddBinder<ITextEditUseCase, ITextEditView>(
                (service, element, view) => new TextEditBinding(service, element, view));
            AddBinder<ICheckUseCase, ICheckView>((service, element, view) => new CheckBinding(service, element, view));
            AddBinder<IChoiceUseCase, IChoiceView>(
                (service, element, view) => new ChoiceBinding(service, element, view));
            AddBinder<IImageUseCase, IImageView>((service, element, view) => new ImageBinding(service, element, view));
            AddBinder<IFileUseCase, IFileView>((service, element, view) => new FileBinding(service, element, view));
            AddBinder<IItemsUseCase, IItemsView>(
                (service, element, view) => new ItemsViewBinding<IItemsUseCase, IItemsView>(service, element, view));
            AddBinder<IUseCase, ICompoundView>(
                (service, element, view) => new CompoundViewBinding(service, element, view));
            AddBinder<INamedItemUseCase, INamedItemView>(
                (service, element, view) => new NamedItemViewBinding(service, element, view));
            AddBinder<IOpenFileUseCase, IOpenFileView>(
                (service, element, view) => new OpenFileViewBinding(service, element, view));
            AddBinder<ISaveFileUseCase, ISaveFileView>(
                (service, element, view) => new SaveFileViewBinding(service, element, view));
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        ///   The add auto binder.
        /// </summary>
        /// <typeparam name="TUseCase"> </typeparam>
        /// <typeparam name="TView"> </typeparam>
        public void AddAutoBinder<TUseCase, TView>() where TUseCase : class, IUseCase where TView : class, IView
        {
            AddBinder<TUseCase, TView>(
                (service, element, view) => new UseCaseAutoBinding<TUseCase, TView>(service, element, view));
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create auto binding.
        /// </summary>
        /// <param name="service">
        /// The service. 
        /// </param>
        /// <param name="obj1">
        /// The obj 1. 
        /// </param>
        /// <param name="obj2">
        /// The obj 2. 
        /// </param>
        /// <returns>
        /// The <see cref="IBinding"/> . 
        /// </returns>
        protected override IBinding CreateAutoBinding(IBindService service, object obj1, object obj2)
        {
            if (obj1 is IUseCase && obj2 is IView)
            {
                return new UseCaseAutoBinding<IUseCase, IView>(service, (IUseCase)obj1, (IView)obj2);
            }

            if (obj2 is IUseCase && obj1 is IView)
            {
                return new UseCaseAutoBinding<IUseCase, IView>(service, (IUseCase)obj2, (IView)obj1);
            }

            return base.CreateAutoBinding(service, obj1, obj2);
        }

        #endregion
    }
}